Skip to content

Potential reimplementation of gitstatus on c++11.#24

Open
starcraftman wants to merge 5 commits intomasterfrom
cxx_gitstatus
Open

Potential reimplementation of gitstatus on c++11.#24
starcraftman wants to merge 5 commits intomasterfrom
cxx_gitstatus

Conversation

@starcraftman
Copy link
Owner

@starcraftman starcraftman commented Jun 26, 2018

  • Haskell still slightly better at parallel usage but performance is
    essentially on par.

I'm not fully decided if I want to do this yet, but I did make a C++ implementation for my own amusement. Won't consider merging until after large Haskell PR already in works. Comments are welcome.

It is mostly done, in that it supports all the features of gitstatus.py. This would unfortunately mean a third implementation. I can definitely maintain this one on my own though.

Performance wise, this implementation is essentially on par with Haskell on my i7. Took best trial of python vs two average runs.

./gitstatus.py  0.03s user 0.02s system 103% cpu 0.051 total
./cxx/build/gitstatus  0.00s user 0.00s system 96% cpu 0.005 total
./cxx/build/gitstatus  0.00s user 0.00s system 95% cpu 0.004 total

Missing

  • Functional tests using new BATS script.
  • Travis test running both googletest and BATS.
  • Code coverage with gcov?
  • Linting custom command in CMake?

- Haskell still slightly better at parallel usage but performance is
essentially on par.
@madnight
Copy link

madnight commented Jun 26, 2018

I would say go for it : ) As long as you have fun with a C++ implementation and people have another useful option they can use, why not.

Rust is also an interesting language, but i guess the absolute ultimate conclusion performance wise would be to use plain C.

@madnight
Copy link

Just for fun https://github.com/madnight/zsh-git-prompt/blob/fun/gitstatus.c

On Arch Linux:

cython --embed gitstatus.py
gcc -Ofast gitstatus.c $(pkg-config --cflags --libs python3) -o gitstatus 

But that does not help:

time ./gitstatus                                                                                                      
fun 0 0 0 0 0 6 3 1 .. 0 0  ./gitstatus  0.04s user 0.01s system 98% cpu 0.053 total

Native C implementation required : )

@starcraftman
Copy link
Owner Author

starcraftman commented Jun 26, 2018

Rust is somewhat known to me, that would introduce the extra dependency though of rust which not all programmers use/install/want (else we'd need to local bootstrap). It is very likely on the other hand that every programmer using zsh-git-prompt has a working C++ compiler, probably with C++11 support. I don't think Rust could go faster. I do find Rust interesting and I like how it enforces safety. That said, it can get a bit tiresome sometimes.

As for C, perhaps. I'd unfortunately lose those nice C++ features. I don't think I can be bothered.

Edit: On topic of making python go faster, pypy will make it go faster but not C fast.

@madnight
Copy link

madnight commented Jun 27, 2018

I'd unfortunately lose those nice C++ features.

Yup, know what you mean, i've written serveral years in C++ (in combination with inline assembly). However, the many features of C++, that have been growing over the years, are also the language biggest deficit. It's a Monster now, where everything is possible in 500 different ways. I'm more a fan of an minimalistic approach and C or let's call it "portable assembly" fits the bill. I think that's why almost all linux /gnu reference implementation are written in C.

Open Source in general:
https://softwareengineering.stackexchange.com/a/113316
Linux and git:
http://harmful.cat-v.org/software/c++/linus

- Join becomes a function taking variable args with initializer list.
- Includes now relative root.
- Some other name cleanups and efficiencies.
- Add YCM config file.
- Small changes to CMake.
- Some code cleanup and a typo.
- Rename library files to be clear.
- Fix header guards.
- Preprend license to source files.
@natemaia
Copy link

natemaia commented Feb 17, 2019

You can get surprisingly good speed out of the shell alone, not c++ fast, but this is about 2X faster than python (probably not at full parody), but has the added bonus of it already being formatted and removes the need for a subshell $()

#!/usr/bin/zsh

git_status()
{
	typeset -i H B G S C M A U # ints
	typeset s='' c="$PWD" b='' d='' x='' y=''

	[[ $COLUMNS -lt 40 || $c =~ ($HOME|boot|bin|etc|usr|dev|lib|proc|sys|var) ]] ||
		git status --porcelain=v2 -b 2>/dev/null |
		{ # parse git status output
			while read l; do case "$l" in
				'u'*) (( U++ )) ;;
				'?'*) (( A++ )) ;;
				*'.head'*) b="${l##*.head }" ;;
				*'.ab'*) l="${l#*.ab +}" H="${l% -*}" B="${l#* -}" ;;
				*[1-2]*) x="${l:2:1}" y="${l:3:1}"
					if [[ $x$y =~ (AA|AU|DD|DU|UA|UD|UU) ]]; then
						(( C++ ))
					else
						[[ $x =~ [ACDMR] ]] && (( G++ ))
						[[ $y =~ [CDMR]  ]] && (( M++ ))
					fi ;;
			esac done
		}

	if [[ $b ]]; then # in a git repo
		while [[ $c && -z $d ]]; do # find .git/
			[[ -d "$c/.git" ]] && d="$c/.git" || c="${c%/*}"
		done
		if [[ -f "$d/refs/stash" ]]; then
			while read l; do
				(( S++ ))
			done < "$d/refs/stash"
		fi
		s="%f$_GIT_PRE$_GIT_BRCH${b}%f"
		(( H )) && s+="$_GIT_AHD${H}"
		(( B )) && s+="$_GIT_BHD${B}"
		s+="$_GIT_SEP"
		(( G )) && s+="$_GIT_STGD${G}"
		(( M )) && s+="$_GIT_CHGD${M}"
		(( C )) && s+="$_GIT_CNFL${C}"
		(( U )) && s+="$_GIT_UNMG${U}"
		(( A )) && s+="$_GIT_UNTR${A}"
		(( ! M && ! C && ! G && ! A && ! U )) && s+="$_GIT_CLN"
		(( S )) && s+="$_GIT_STSH${S}"
		s+="$_GIT_SUF%f"
	fi
	printf "%s" "$s"
}

: "${_GIT_PRE="("}"
: "${_GIT_SEP="|"}"
: "${_GIT_SUF=")"}"
: "${_GIT_BRCH="%F{magenta}"}"
: "${_GIT_CNFL="%F{red}x%f"}"
: "${_GIT_CHGD="%F{blue}+%f"}"
: "${_GIT_UNMG="%F{yellow}*%f"}"
: "${_GIT_CLN="%F{green}%{✔%G%}%f"}"
: "${_GIT_STGD="%F{red}%{•%G%}%f"}"
: "${_GIT_AHD="%F{green}%{↑%G%}%f"}" # ⇡
: "${_GIT_BHD="%F{red}%{↓%G%}%f"}"   # ⇣
: "${_GIT_UNTR="%F{yellow}%{…%G%}%f"}"
: "${_GIT_STSH="%F{blue}%{⚑%G%}%f"}"

git_status

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants